package com.seek.inter;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.lang.reflect.Method;
import java.net.URLEncoder;
import java.util.Date;
import java.util.UUID;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.seek.cache.CacheUtil;
import com.seek.inter.interdto.InterDtoUser;
import com.seek.model.dto.ResultInfo;
import com.seek.model.entity.TInter;
import com.seek.model.entity.TInterLog;
import com.seek.util.CommonUtil;
import com.seek.util.ConstantsUtil;
import com.seek.util.InterLogUtil;
import com.seek.util.JsonUtil;
import com.seek.util.MD5Util;
import com.seek.util.WebUtil;

@Controller
@RequestMapping("/service")
public class InterEnterController {
private Logger logger = LoggerFactory.getLogger(InterEnterController.class);
	
	@Resource
	private InterLogUtil interLogUtil;
	
	/**
	 * 接口入口  只接受post方法
	 * @param request
	 * @return
	 * @throws Exception
	 */
	@RequestMapping(method=RequestMethod.POST)
	public void enter(HttpServletRequest request,HttpServletResponse response) throws Exception {
		ResultInfo result = new ResultInfo();		
		
		BufferedReader br = new BufferedReader(new InputStreamReader(request.getInputStream(), "utf-8"));
		String line = null;
		StringBuffer reqJson = new StringBuffer();
		while ((line = br.readLine()) != null) {
			reqJson.append(line);
		}
		br.close();
		String reqStr = reqJson.toString();
		logger.info("reqstr==" + reqStr);
		
		Date reqTime = new Date();
		String interId = request.getParameter("interId");
		if ("getServerTime".equals(interId)){
			result.setStatus(0);
			result.setMessage("");
			result.setBody(reqTime.getTime());
			String respStr = JsonUtil.toJsonString(result);
			WebUtil.write(response, respStr, "utf-8","application/json");
			return;
		}
		
		String uuid = UUID.randomUUID().toString();
		JSONObject jsonObject = JSON.parseObject(reqStr);
		interId = jsonObject.getString("interId");
		String ver = jsonObject.getString("ver");
		interId = interId +"_"+ver;
		String time = request.getParameter("time");
		String token = request.getParameter("token");
		
//		if (interId !=null && ConstantsUtil.DEBUG_MODE != 1){
//			// 记录IP的请求数，并做IP的请求限制：按分钟来
//			if (!updateAndCheckIPLimit(request)){
//				result.setStatus(104);
//				result.setMessage("访问太频繁，请稍后再试");
//				String respStr = JsonUtil.toJsonString(result);
//				WebUtil.write(response, respStr, "utf-8","application/json");
//				return;
//			}
//		}
		
		// 取得接口定义
		TInter inter = CacheUtil.getInter(interId);	
		if (inter == null || inter.getIsUsed() == 0){
			result.setStatus(105);
			result.setMessage("您的版本不支持该服务，请升级软件");
			String respStr = JsonUtil.toJsonString(result);
			WebUtil.write(response, respStr, "utf-8","application/json");
			return;
		}
		InterDtoUser user = null;
		if (!ConstantsUtil.DEFAULT_TOKEN.equals(token)){
			user = CacheUtil.getLoginCache(token);
			if (user != null && user.getIsUsed() == 0){
				result.setStatus(100);
				result.setMessage("用户未登录或登录已失效！");
				String respStr = JsonUtil.toJsonString(result);
				WebUtil.write(response, respStr, "utf-8","application/json");
				return;
			}
		}
//		// 再做一次校验，如果有传入uid，判断uid与token对应的用户之间是否匹配
//		String userId = jsonObject.getString("userId");
//		if (user != null && userId != null && !userId.equals(user.getId()) && inter.getNeedLogin() != 0){
//			result.setStatus(100);
//			result.setMessage("非法用户！");
//		}else{
			if(ConstantsUtil.DEFAULT_TOKEN.equals(token) || user != null) {
				String currentSign="";
				String sign = request.getParameter("sign");
				String signStr = "time" + time + "token" + token + reqStr + ConstantsUtil.SIGN_KEY;
				signStr = signStr.replaceAll(" ", "");
				signStr = signStr.replaceAll("\\*", "");
				signStr = URLEncoder.encode(signStr, "UTF-8");
				currentSign = MD5Util.MD5(signStr).toLowerCase();

				if(currentSign.equals(sign)) {
					if(StringUtils.isEmpty(interId)) {
						result.setStatus(1);
						result.setMessage("接口编号不能为空");
					} else {
						if(inter != null) {	
							// 把tocken存入jsonObject中，用于其它地方调用
							if (!jsonObject.containsKey("token"))
								jsonObject.put("token", token);
							if (user != null){
								jsonObject.put("_currnetUserId",user.getId());
								if (!jsonObject.containsKey("hidePhone"))
									jsonObject.put("hidePhone", user.getHidePhone());
							}else{
								jsonObject.put("hidePhone", 1);
							}
							// 调用的业务类
							String invokeClass = inter.getClassName();
							// 调用的业务方法
							String invokeMethod = inter.getMethodName();

							// 执行调用
							Class<?> callClass = Class.forName(invokeClass);
							Object o = callClass.newInstance();
							Method callMethod = callClass.getMethod(invokeMethod, HttpServletRequest.class,JSONObject.class);
							try {
								result = (ResultInfo)callMethod.invoke(o,request,jsonObject);
							} catch (Exception e) {
								logger.error("系统异常",e);
								result.setStatus(1);
								result.setMessage("系统繁忙！");
							}
						}
					}
				} else {
					result.setStatus(102);
					result.setMessage("签名不通过！");
				}
			} else {
				result.setStatus(100);
				result.setMessage("用户未登录或登录已失效！");
			}
//		}
		
		String respStr = JsonUtil.toJsonString(result);
		Date respTime = new Date();		
		TInterLog interLog = new TInterLog();
		interLog.setConsumeTime(respTime.getTime() - reqTime.getTime());
		interLog.setInterId(interId);
		interLog.setReqStr(reqStr);
		interLog.setRespStr(respStr);
		interLog.setReqTime(reqTime);
		interLog.setRespTime(respTime);
		interLog.setUuid(uuid);
		if (user != null){
			interLog.setUid(user.getId());
		}
		interLogUtil.addInterLog(interLog);
		WebUtil.write(response, respStr, "utf-8","application/json");
	}
	
	private boolean updateAndCheckIPLimit(HttpServletRequest request) throws Exception{
		
		String ip = WebUtil.getIpAddr(request);
		int count = CommonUtil.getIntValue(CacheUtil.getRedisData("IP_LIMIT_"+ip));
		
		if (count +  1 > 100){
			return false;
		}
		// 初次访问
		if (count == 0){
			CacheUtil.putRedisDataEx("IP_LIMIT_"+ip, "1", 60L);
		}else{
			CacheUtil.incr("IP_LIMIT_"+ip);
		}
		
		return true;
	}
}
